package com.project.easy.common.framework.web.validator;

import  com.project.easy.common.util.collection.CollectionUtil;
import  com.project.easy.common.util.enums.exception.ValidatorExceptionEnums;
import com.project.easy.common.framework.web.exception.ParamValidatorException;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

import java.util.Set;

import static javax.validation.Validation.buildDefaultValidatorFactory;

/**
 * @author GreatorMan.cool
 * @copyright: Copyright (c) 2020
 * @company: 扬起科技有限公司
 * @date 2021/10/3 22:16
 * @description: 数据验证
 */
public final class ValidatorTool {
    /**
     * 私有构造方法
     */
    private ValidatorTool() {
    }

    private static Validator validator;

    static {
        ValidatorFactory factory = buildDefaultValidatorFactory();
        validator = factory.getValidator();
        // 快速返回模式
/*        validator = Validation.byProvider(HibernateValidator.class)
                .configure()
                .failFast(true)
                .buildValidatorFactory()
                .getValidator();*/
    }

    /**
     * 获取验证错误信息
     * @return 返回验证器
     */
    public static Validator getValidator() {
        return validator;
    }
    /**
     * 校验参数，用于普通参数校验 [未测试！]
     * @param  params 验证参数
     */
    public static void validateParams(Object params) {
        Set<ConstraintViolation<Object>> constraintViolationSet = validator.validate(params);
        parseExceptionErrorMsg(constraintViolationSet);
    }
    /**
     * 校验对象
     * @param object 对象
     * @param groups 组合
     * @param <T> 数据类型
     */
    public static <T> void validate(T object, Class<?>... groups) {
        Set<ConstraintViolation<T>> constraintViolationSet = validator.validate(object, groups);
        parseExceptionErrorMsg(constraintViolationSet);
    }
    /**
     * 解析业务异常 如果有异常则抛出异常信息
     * @param constraintViolationSet 异常信息
     * @param <T> 对象数据
     */
    private static <T> void parseExceptionErrorMsg(Set<ConstraintViolation<T>> constraintViolationSet) {
        if (!CollectionUtil.isNull(constraintViolationSet)) {
            StringBuilder errorMsg = new StringBuilder();
            for (ConstraintViolation<T> constraintViolation : constraintViolationSet) {
                if (errorMsg.length() > 0) {
                    errorMsg.append("\n");
                }
                errorMsg.append(constraintViolation.getMessage());
            }
            throw new ParamValidatorException(ValidatorExceptionEnums.VALIDATOR_PARAM_ILLEGAL.getCode(), errorMsg.toString());
        }
    }

}
